﻿using System;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using net.xBei.Models;
using net.xBei.Models.json;

namespace net.xBei.WebApi.Helper; 
/// <summary>
/// 
/// </summary>
public static class HttpContextHelper {
    /// <summary>
    /// 是否系统用户
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    public static bool IsSystemUser(this HttpContext context) => IsSystemUser(context.User);
    /// <summary>
    /// 是否系统用户
    /// </summary>
    /// <param name="contextUser"></param>
    /// <returns></returns>
    public static bool IsSystemUser(this ClaimsPrincipal contextUser) {
        var userId = contextUser.Identity?.Name;
        return userId == CommonConsts.SystemUserId;
    }
    /// <summary>
    /// 是否系统用户
    /// </summary>
    /// <param name="authorizationContext"></param>
    /// <returns></returns>
    public static bool IsSystemUser(this AuthorizationHandlerContext authorizationContext)
        => authorizationContext.User.IsSystemUser();
    /// <summary>
    /// 从Context中获取用户ID
    /// </summary>
    /// <param name="httpContext"></param>
    /// <returns></returns>
    public static int GetUserId(this HttpContext httpContext) {
        if (httpContext != null && httpContext.User != null && httpContext.User.Identity != null && !string.IsNullOrEmpty(httpContext.User.Identity.Name)) {
            var userIdString = httpContext.User.Identity.Name;
            if (int.TryParse(userIdString, out var userId)) {
                return userId;
            }
        }
        return -1;
    }
    /// <summary>
    /// 
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="responseData"></param>
    /// <returns></returns>
    public static IActionResult GetActionResult<T>(this ResponseData<T> responseData) => new OkObjectResult(responseData);
    /// <summary>
    /// 
    /// </summary>
    /// <param name="responseData"></param>
    /// <returns></returns>
    public static IActionResult GetActionResult(this ResponseData responseData) => new OkObjectResult(responseData);
    /// <summary>
    /// 
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="responseData"></param>
    /// <returns></returns>
    public static async Task<IActionResult> GetActionResultAsync<T>(this Task<ResponseData<T>> responseData) {
        var data = await responseData;
        if (data.Success && data.Data is IActionResult actionResult) return actionResult;
        return new OkObjectResult(data);
    }
    /// <summary>
    /// 
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="responseData"></param>
    /// <returns></returns>
    public static async Task<ActionResult<ResponseData<T>>> GetResultAsync<T>(this Task<ResponseData<T>> responseData) {
        var data = await responseData;
        if (data.Success && data.Data is ActionResult<ResponseData<T>> actionResult) return actionResult;
        return new OkObjectResult(data);
    }
    
    /// <summary>
    /// 
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="responseData"></param>
    /// <returns></returns>
    public static async Task<IActionResult> FixBatchResultAsync<T>(this Task<ResponseData<ResponseData.Batch<T>>> responseData) {
        var result = await responseData;
        if (result.Success) {
            if ((result.Data.Fails?.Any()) != true) {
                //全部成功
                if (result.Data.Success?.Count() == 1) {
                    //只有一个值
                    return new OkObjectResult(ResponseData.Ok(result.Data.Success.FirstOrDefault()));
                }
            }
            return new OkObjectResult(result);
        }
        //全部失败
        if (result.Data.IsEmpty || result.Data.Fails == null) {
            return new OkObjectResult(ResponseData.Error(result.Message ?? "未知错误", result.Data, result.Code));
        }
        if (result.Data.Fails.Count() == 1) {
            //只有一个值
            var fail = result.Data.Fails.FirstOrDefault();
            return new OkObjectResult(ResponseData.Error(fail.Message ?? "未知错误", code: fail.Code));
        }
        return new OkObjectResult(result);
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="responseData"></param>
    /// <returns></returns>
    public static async Task<IActionResult> GetActionResultAsync(this Task<ResponseData<FileStreamResult>> responseData) {
        var r = await responseData;
        if (r.Success && r.Data is IActionResult actionResult) return actionResult;
        return new OkObjectResult(r);
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="responseData"></param>
    /// <returns></returns>
    public static async Task<IActionResult> GetActionResultAsync(this Task<ResponseData> responseData) {
        var data = await responseData;
        if (data.Success && data.Data is IActionResult actionResult) return actionResult;
        return new OkObjectResult(data);
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="responseData"></param>
    /// <param name="errHandler"></param>
    /// <returns></returns>
    public static async Task<IActionResult> GetActionResultAsync(this Task<ResponseData> responseData, Action<ResponseData> errHandler) {
        var data = await responseData;
        if (data.Success && data.Data is IActionResult actionResult) return actionResult;
        if (data.Success == false) try { errHandler.Invoke(data); } catch { }
        return new OkObjectResult(data);
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="responseData"></param>
    /// <param name="errHandler"></param>
    /// <returns></returns>
    public static async Task<IActionResult> GetActionResultAsync(this Task<ResponseData> responseData, Func<ResponseData, Task> errHandler) {
        var data = await responseData;
        if (data.Success && data.Data is IActionResult actionResult) return actionResult;
        if (data.Success == false) try { await errHandler.Invoke(data); } catch { }
        return new OkObjectResult(data);
    }
}
